package main;

import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.image.ImageObserver;

import stateManager.StateManager;
import soundManager.SoundManager;

public abstract class Sprite implements Commons, Runnable, Comparable<Sprite>
{
	protected boolean visible;
	private Image image;
	protected boolean collided;
	protected int x;
	protected int y;
	protected boolean dying;
	protected int dx;
	protected int dy;
	protected double acceleration = 0;
	protected int friction = 1;
	protected double speed = 0;
	protected int heading = 0;
	protected int health;
	protected int width;
	protected int height;
	protected int rotateRate = 2;
	protected int drawOrder = 0;
	protected String name;
	protected Graphics2D g;
	protected ImageObserver imageObserver;
	protected boolean wasChecked;
	protected boolean wasThought;
	protected boolean collidable = true;
	protected boolean alive = true;
	public GameTree gameTree;
	public StateManager stateManager;
	public SoundManager soundManager;

	protected int life;

	public Sprite() {
		stateManager = StateManager.getInstance();
		soundManager = SoundManager.getInstance();
		wasChecked = false;
		wasThought = false;
		visible = true;
		alive = true;
		collided = false;
		this.name = "default";
	}
	public void die() {
		visible = false;
		alive = false;
		this.dying = false;
	}
	public void setGameTree(GameTree tree) {
		gameTree = tree;
	}
	public boolean isAlive() {
		return alive;
	}
	protected void setAlive(boolean a) {
		this.alive = a;
	}
	public boolean isVisible() {
		return visible;
	}
	protected void setVisible(boolean visible) {
		this.visible = visible;
	}
	public boolean isCollidable() {
		return collidable;
	}
	protected void setCollidable(boolean c) {
		this.collidable = c;
	}
	public void setImage(Image image) {
		this.image = image;
	}
	public Image getImage() {
		return image;
	}
	public void setG(Graphics2D g) {
		this.g = g;
	}
	public Graphics2D getG() {
		return g;
	}
	public void setName(String name) {
		if(name == "") {
			this.name = "x =  " + this.x + "  y =  " + this.y;
		}
		else {
			this.name = name;
		}
	}
	public String getName() {
		return this.name;
	}
	public void setImgObserver(ImageObserver imgOb) {
		this.imageObserver = imgOb;
	}
	public ImageObserver getImgObserver() {
		return this.imageObserver;
	}
	public void setLife(int x) {
		this.life = x;
	}
	public int getLife() {
		return life;
	}
	public int myRandom(int Min, int Max) {
		return(Min + (int)(Math.random() * ((Max - Min) + 1)));
	}
	public void setZ(int x) {
		this.drawOrder = x;
	}
	public int getZ() {
		return drawOrder;
	}
	public void setWidth(int x) {
		this.width = x;
	}
	public int getHeight() {
		return height;
	}
	public void setHeight(int x) {
		this.height = x;
	}
	public int getWidth() {
		return width;
	}
	public void setX(int x) {
		this.x = x;
	}
	public void setAccerlation(double x) {
		this.acceleration = x;
	}        
	public void setHealth(int x) {
		this.health = x;
	}        
	public int getHealth() {
		return this.health;
	}        
	public void setSpeed(int x) {
		this.speed = x;
	}
	public void setFriction(int x) {
		this.friction = x;
	}        
	public void setHeading(int x) {
		this.heading = x;
	}
	public void setY(int y) {
		this.y = y;
	}
	public int getY() {
		return y;
	}
	public int getX() {
		return x;
	}
	public double getSpeed() {
		return speed;
	}        
	public int getFriction() {
		return friction;
	}        
	public double getAcceleration() {
		return acceleration;
	}        
	public int getHeading() {
		return heading;
	}        
	public void setDying(boolean dying) {
		this.dying = dying;
	}
	public boolean isDying() {
		return this.dying;
	}
	public int getDx() {
		return dx;
	}
	public void setDx(int dx) {
		this.dx = dx;
	}
	public int getDy() {
		return dy;
	}
	public void setDy(int dy) {
		this.dy = dy;
	}
	public boolean getWasChecked() {
		return wasChecked;
	}
	public void setChecked(boolean check) {
		wasChecked = check;
	}
	public boolean getWasThought() {
		return wasThought;
	}
	public void setThought(boolean thought) {
		wasThought = thought;
	}
	public void run(){

		this.think();

	}
	@Override
	public int compareTo(Sprite o) {
		if(this.drawOrder >= o.getZ()){
			return 1;
		}
		return 0;
	}

	/****************************************
	 * all functions past this can be overridden to have your own
	 * functionality.
	 ****************************************/
	public abstract void draw();
	public abstract void think();
	public abstract boolean doesCollide(Sprite s);
}
